#ifndef ML307G_MQTT_H
#define ML307G_MQTT_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif


    // 平台适配：提供 UART 发送与毫秒计时、延时、互斥（可选）
    typedef int (*ml307g_uart_write_fn)(const uint8_t *buf, size_t len);
    typedef uint32_t (*ml307g_millis_fn)(void);
    typedef void (*ml307g_delay_ms_fn)(uint32_t ms);

    // 事件回调
    typedef void (*ml307g_on_connected_fn)(int conn_state); // 0/1，依据 +MQTTURC:"conn",<id>,<state>
    typedef void (*ml307g_on_msg_fn)(const char *topic, const uint8_t *payload, size_t len, int qos);
    typedef void (*ml307g_on_puback_fn)(int pktid);

typedef struct {
    uint8_t connect_id; // 默认 0
    uint8_t version; // 3=MQTT3.1.1，5=MQTT5（以手册为准）
    uint16_t keepalive_s; // 例如 60
    uint8_t clean_session; // 0/1
    const char *client_id;
    const char *username;
    const char *password;
    // 遗嘱、编码、自动重连等，可按需扩展
    int reconn_times; // -1 持续重连；>=0 次数
    int reconn_interval_s; // 间隔
} ml307g_mqtt_cfg_t;


// PDP/APN 配置（非 MQTT 手册，但常用 4G 上网流程）
typedef struct {
    const char *apn;
    const char *user;
    const char *pwd;
} ml307g_pdp_cfg_t;


// 句柄
typedef struct {
    // 平台绑定
    ml307g_uart_write_fn write;
    ml307g_millis_fn millis;
    ml307g_delay_ms_fn delay_ms;

    // 回调
    ml307g_on_connected_fn on_connected;
    ml307g_on_msg_fn on_msg;
    ml307g_on_puback_fn on_puback;

    // 状态
    ml307g_mqtt_cfg_t mqtt;
    int linked; // 注册/附着/激活
    int mqtt_ready; // 已配置 + 建链

    // 解析缓冲
    char line[256];
    size_t line_len;
} ml307g_t;


// 初始化/绑定平台接口
void ml307g_init(ml307g_t *h, ml307g_uart_write_fn wr, ml307g_millis_fn ms, ml307g_delay_ms_fn d);


// 4G 基础：建议顺序
// 1) AT；2) 关闭回显；3) 获取/注册网络；4) 附着；5) 激活 PDP
int ml307g_modem_basic(ml307g_t *h);
int ml307g_set_apn(ml307g_t *h, const ml307g_pdp_cfg_t *pdp);
int ml307g_pdp_activate(ml307g_t *h, int cid); // 常用 cid=1


// MQTT：CFG/CONN/SUB/PUB/READ/STATE/DISC
int ml307g_mqtt_cfg(ml307g_t *h, const ml307g_mqtt_cfg_t *cfg);
int ml307g_mqtt_connect(ml307g_t *h, const char *host, uint16_t port);
int ml307g_mqtt_sub(ml307g_t *h, const char *topic, int qos);
int ml307g_mqtt_unsub(ml307g_t *h, const char *topic);
int ml307g_mqtt_pub(ml307g_t *h, const char *topic, const uint8_t *payload, size_t len, int qos, int retain);
int ml307g_mqtt_read(ml307g_t *h); // 触发读取缓存（依据手册 AT+MQTTREAD）
int ml307g_mqtt_state(ml307g_t *h);
int ml307g_mqtt_disc(ml307g_t *h);


// UART 接收每个字节喂给解析器；在主循环/任务中调用。
void ml307g_feed_byte(ml307g_t *h, uint8_t ch);


#ifdef __cplusplus
}
#endif


#endif // ML307G_MQTT_H